/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.compomics.spestimator.files.fasta.clear;

import com.compomics.dbtoolkit.toolkit.ClearRedundancy;
import com.compomics.spestimator.files.fasta.digest.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;

/**
 *
 * @author Kenneth
 */
public class FastaCleanup {

    private static final String DBTOOLKIT_CLASS_NAME = "com.compomics.dbtoolkit.toolkit.ClearRedundancy";
    private static final Logger LOGGER = Logger.getLogger(FastaDigester.class);
    private static final String enzymeName = "Trypsin";
    private static String speciesName;
    private static int accessionCounter = 0;
    private static Object currentHeader;

    public static void clearRedundancy(File inputFile, File outputFile) throws IOException {
        // Usage:--temp <tempFolder> --output <output_file_name> <input_db_name>
        LOGGER.info("Clearing redundancy merged fastafile using dbToolkit : ");
        File temporaryOutput = new File(outputFile.getParentFile(), outputFile.getName().toUpperCase().replace(".FASTA", "temp.FASTA"));
        File temp = createTempDir("spes_" + System.currentTimeMillis());
        ArrayList<String> arguments = new ArrayList<>();
        arguments.add("--output");
        arguments.add(temporaryOutput.getAbsolutePath());
        arguments.add("--temp");
        arguments.add(temp.getAbsolutePath());
        arguments.add(inputFile.getAbsolutePath());
        System.out.println(arguments.toString().replace(",", " "));
        String[] argumentsAsArray = new String[arguments.size()];
        ClearRedundancy.main(arguments.toArray(argumentsAsArray));
        LOGGER.info("Created fastafile bearing peptides only unique to the set species...");
        rewriteWithDecoys(temporaryOutput, outputFile);
        temporaryOutput.delete();
    }

    public static void main(String[] args) {
        try {
            File input = new File(FastaDigester.class.getResource("/output_digested.FASTA").toURI());
            File output = new File(FastaDigester.class.getResource("/output_unique.FASTA").toURI());
            clearRedundancy(input, output);
            System.out.println(output.getAbsolutePath());
            try (InputStream in = new FileInputStream(output);
                    BufferedReader reader =
                    new BufferedReader(new InputStreamReader(in))) {
                String line = null;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException x) {
                System.err.println(x);
            }
        } catch (URISyntaxException ex) {
            java.util.logging.Logger.getLogger(FastaDigester.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(FastaCleanup.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static File createTempDir(String prefix)
            throws IOException {
        String tmpDirStr = System.getProperty("java.io.tmpdir");
        if (tmpDirStr == null) {
            throw new IOException(
                    "System property 'java.io.tmpdir' does not specify a tmp dir");
        }

        File tmpDir = new File(tmpDirStr);
        if (!tmpDir.exists()) {
            boolean created = tmpDir.mkdirs();
            if (!created) {
                throw new IOException("Unable to create tmp dir " + tmpDir);
            }
        }

        File resultDir = null;
        int suffix = (int) System.currentTimeMillis();
        int failureCount = 0;
        do {
            resultDir = new File(tmpDir, prefix + suffix % 10000);
            suffix++;
            failureCount++;
        } while (resultDir.exists() && failureCount < 50);

        if (resultDir.exists()) {
            throw new IOException(failureCount
                    + " attempts to generate a non-existent directory name failed, giving up");
        }
        boolean created = resultDir.mkdir();
        if (!created) {
            throw new IOException("Failed to create tmp directory");
        }

        return resultDir;
    }

    private static void rewriteWithDecoys(File fasta, File outputFile) throws IOException {
        StringBuilder sequence = null;
        String strLine = null;
        RandomAccessFile file = new RandomAccessFile(fasta, "rw");
        PrintWriter out = new PrintWriter(new FileOutputStream(outputFile, true));
        try {
            sequence = new StringBuilder();
            currentHeader = null;
            while (file.getFilePointer() < file.length()) {
                strLine = file.readLine();
                if (strLine.startsWith(">")) {
                    speciesName = strLine.substring(strLine.indexOf("|") + 1, strLine.indexOf("SPESNR"));
                    if (currentHeader != null) {
                        writeSequenceToFasta(sequence, out);
                    }
                    //start a new sequence
                    currentHeader = strLine.substring(1);
                } else {
                    sequence.append(strLine);
                }
            }
            if (!sequence.toString().isEmpty()) {
                try {
                    writeSequenceToFasta(sequence, out);
                } catch (StringIndexOutOfBoundsException e) {
                    LOGGER.error("Invalid format");
                }
            }
        } catch (Exception e) {//Catch exception if any
            e.printStackTrace();
        } finally {
        }
    }

    /* private static void rewriteWithDecoys2(File fasta, File outputFile) throws IOException {
     StringBuilder sequence = null;
     String strLine = null;
     RandomAccessFile file = new RandomAccessFile(fasta, "rw");
     PrintWriter out = new PrintWriter(new FileOutputStream(outputFile, true));
     boolean saveAccession = true;
     try {
     accessionCounter = 0;
     sequence = new StringBuilder();
     String currentHeader = null;
     while (file.getFilePointer() < file.length()) {
     accessionCounter++;
     strLine = file.readLine();
     if (strLine.startsWith(">")) {
     if (currentHeader != null) {
     if (!strLine.contains("^A")) {
     currentHeader = strLine.substring(1);
     writeSequenceToFasta(strLine, sequence, out);
     } else {
     currentHeader = null;
     sequence = sequence.delete(0, sequence.length());
     }
     }
     //start a new sequence
     } else {
     sequence.append(strLine);
     }
     }
     } catch (Exception e) {//Catch exception if any
     e.printStackTrace();
     } finally {
     }
     }*/
    private static void writeSequenceToFasta(StringBuilder sequence, PrintWriter out) {
        if (sequence.length() >= 5) {
            accessionCounter++;
            out.println(">generic|" + speciesName + "_" + getTimeStamp() + accessionCounter + "|" + accessionCounter);
            out.println(sequence.toString());
            out.println(">generic|" + speciesName + "_" + getTimeStamp() + accessionCounter + "-REVERSED" + "|" + accessionCounter + "-REVERSED");
            out.println(sequence.reverse().toString());
            out.flush();
        } else {
            LOGGER.debug("Sequence smaller than 5 amino acids will be skipped");
        }
        sequence = sequence.delete(0, sequence.length());
    }

    private static String getTimeStamp() {
        String timestamp = String.valueOf(System.currentTimeMillis());
        return timestamp.substring(timestamp.length() - 4);
    }
}
